package com.tanhua.manage.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.manage.enums.AgeRangeEnum;
import com.tanhua.manage.enums.AreaEnum;
import com.tanhua.manage.enums.LogTypeEnum;
import com.tanhua.manage.enums.SexEnum;
import com.tanhua.manage.mapper.LogMapper;
import com.tanhua.manage.mapper.UserInfoMapper;
import com.tanhua.manage.pojo.Log;
import com.tanhua.manage.pojo.UserInfo;
import com.tanhua.manage.pojo.Year;
import com.tanhua.manage.utils.RateUtils;
import com.tanhua.manage.vo.DistributionVo;
import com.tanhua.manage.vo.Summary;
import com.tanhua.manage.vo.Vo;
import com.tanhua.manage.vo.YearVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class DashboardService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private LogMapper logMapper;

    @Autowired
    private LogService logService;

    public Summary querySummary() {
        //获取userInfo数据
        List<UserInfo> userInfoList = userInfoMapper.selectList(null);
        //创建返回值
        Summary summary = new Summary();
        //累计用户
        summary.setCumulativeUsers(userInfoList.size());
        //今日新增用户
        int todNew = 0;
        //昨日新增用户
        int yesNew = 0;
        Calendar cal5 = Calendar.getInstance();
        cal5.setTime(new Date());
        cal5.add(Calendar.DAY_OF_YEAR, -1);

        Date yesDate = cal5.getTime();
        for (UserInfo userInfo : userInfoList) {
            Date created = userInfo.getCreated();
            Date now = new Date();
            String today = new SimpleDateFormat("yyyy-MM-dd").format(now);
            String yestoday = new SimpleDateFormat("yyyy-MM-dd").format(yesDate);
            String before = new SimpleDateFormat("yyyy-MM-dd").format(created);
            if (today.equals(before)) {
                todNew++;
            }
            if (yestoday.equals(before)) {
                yesNew++;
            }
        }
        summary.setNewUsersToday(todNew);
        //30天活跃用户
        List<Log> logList = logMapper.selectList(null);
        //设置存储用户id的set集合用于去重
        Set<Integer> months = new HashSet<>();
        Set<Integer> weeks = new HashSet<>();
        Set<Integer> yesDays = new HashSet<>();
        Set<Integer> toDays = new HashSet<>();
        Set<Integer> beyesDays = new HashSet<>();
        int tdLoginNum = 0;
        int yesLoginNum = 0;

        Long dayTime = 0L;
        for (Log log : logList) {

            //获取活跃时间
            Date activeTime = log.getActiveTime();
            String activeTimeStr = new SimpleDateFormat("yyyy-MM-dd").format(activeTime);
            //30天
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.add(Calendar.DAY_OF_YEAR, -30);
            //7天
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(new Date());
            cal2.add(Calendar.DAY_OF_YEAR, -7);

            //3天
            Calendar cal6 = Calendar.getInstance();
            cal6.setTime(new Date());
            cal6.add(Calendar.DAY_OF_YEAR, -3);
            //2天
            Calendar cal3 = Calendar.getInstance();
            cal3.setTime(new Date());
            cal3.add(Calendar.DAY_OF_YEAR, -2);
            //1天
            Calendar cal4 = Calendar.getInstance();
            cal4.setTime(new Date());
            cal4.add(Calendar.DAY_OF_YEAR, -1);

            Date mDate = cal.getTime();
            Date wDate = cal2.getTime();
            Date bdDate = cal3.getTime();
            Date dDate = cal4.getTime();
            Date byDate = cal6.getTime();

            try {
                //30天内活跃
                if (new SimpleDateFormat("yyyy-MM-dd").parse(activeTimeStr).getTime() > mDate.getTime()) {
                    months.add(log.getUserId());
                }
                //7天活跃
                if (new SimpleDateFormat("yyyy-MM-dd").parse(activeTimeStr).getTime() > wDate.getTime()) {
                    weeks.add(log.getUserId());
                    //7天总使用时长
                    //执行了登录方法
                    long Time = 0L;
                    if (LogTypeEnum.LOGIN.getValue().equals(log.getMethod())) {
                        //获取登录时间
                        Date logTime = log.getActiveTime();
                        //创建新时间记录登录时间用于比较
                        Date tempTime = logTime;
                        String logTimeStr = new SimpleDateFormat("yyyy-MM-dd").format(logTime);
                        Integer userId = log.getUserId();
                        //获取此用户操作的所有方法
                        QueryWrapper<Log> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("user_id", userId);
                        List<Log> logList2 = logMapper.selectList(queryWrapper);
                        for (Log log2 : logList2) {
                            Date activeTime2 = log2.getActiveTime();
                            String activeTime2Str = new SimpleDateFormat("yyyy-MM-dd").format(activeTime2);
                            //此用户今天操作的方法
                            if (logTimeStr.equals(activeTime2Str)) {
                                tempTime = tempTime.compareTo(activeTime2) > 0 ? tempTime : activeTime2;
                            }
                        }
                        Time = tempTime.getTime() - logTime.getTime();
                    }
                    dayTime += Time;
                }
                //今日活跃
                Date now = new Date();
                String today = new SimpleDateFormat("yyyy-MM-dd").format(now);
                String after = new SimpleDateFormat("yyyy-MM-dd").format(activeTime);
                if (today.equals(after)) {
                    toDays.add(log.getUserId());
                    //今日登录次数
                    if (LogTypeEnum.LOGIN.getValue().equals(log.getMethod())) {
                        tdLoginNum++;
                    }
                }
                //昨日活跃
                if (new SimpleDateFormat("yyyy-MM-dd").parse(activeTimeStr).getTime() > bdDate.getTime()
                        && new SimpleDateFormat("yyyy-MM-dd").parse(activeTimeStr).getTime() < dDate.getTime()) {
                    yesDays.add(log.getUserId());
                    //昨日登录次数
                    if (LogTypeEnum.LOGIN.getValue().equals(log.getMethod())) {
                        yesLoginNum++;
                    }
                }
                //前天活跃
                if (new SimpleDateFormat("yyyy-MM-dd").parse(activeTimeStr).getTime() > byDate.getTime()
                        && new SimpleDateFormat("yyyy-MM-dd").parse(activeTimeStr).getTime() < bdDate.getTime()) {
                    beyesDays.add(log.getUserId());

                }
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }

        summary.setActivePassMonth(months.size());//30天活跃
        summary.setActivePassWeek(weeks.size());//7天
        summary.setActiveUsersToday(toDays.size());//今日活跃
        summary.setActiveUsersYesterday(yesDays.size());//昨日活跃
        summary.setLoginTimesToday(tdLoginNum);//今日登录次数
        summary.setUseTimePassWeek(Integer.parseInt(dayTime.toString()));

        //计算涨跌率
        summary.setNewUsersTodayRate(RateUtils.computeRate(todNew, yesNew));//今日新增用户涨跌率
        summary.setActiveUsersTodayRate(RateUtils.computeRate(toDays.size(), yesDays.size()));//今日活跃用户涨跌率
        summary.setLoginTimesTodayRate(RateUtils.computeRate(tdLoginNum, yesLoginNum));//今日登录次数涨跌率
        summary.setActiveUsersYesterdayRate(RateUtils.computeRate(yesDays.size(), beyesDays.size()));//昨日活跃用户涨跌率
        return summary;
    }
/**活跃用户
* queryData
* @param
*/
    public YearVo queryData(Long sd, Long ed, Integer type) {
        Date date = new Date(sd);
        int count = 0;
        int amount = 0;
        //用户详情
        QueryWrapper<UserInfo> query = new QueryWrapper<>();
        List<UserInfo> userInfos = userInfoService.queryUserInfoList(query);
        //日志表
        QueryWrapper<Log> queryWrapper = new QueryWrapper<>();
        List<Log> logs = this.logMapper.selectList(queryWrapper);

        long day = (ed - sd) / (1000L * 60 * 60 * 24);

        List<Year> thisYear = new ArrayList<>();
        List<Year> lastYear = new ArrayList<>();
        YearVo yearVo = new YearVo();

        switch (type) {
            //新增用户
            case (101):
                 /*   List<Year> thisYear = new ArrayList<>();
                List<Year> lastYear = new ArrayList<>();

                Date created = null;

                Year y = new Year();
                Year y2 = new Year();
                for (UserInfo userInfo : userInfos) {
                    created = userInfo.getCreated();

                    //今年
                    if (created.getTime() >= sd && created.getTime() <= ed) {
                        count++;

                        Calendar calendar = Calendar.getInstance();
                        calendar.setTimeInMillis(ed - sd);
                        y.setTitle("近" + calendar.get(Calendar.DAY_OF_MONTH) + "天");
                    }

                    y.setAmount(count);
                    thisYear.add(y);


                    //去年
                    // for (int j = 1; j <= day; j++) {
                    if (created.getTime() >= sd - 1000L * 60 * 60 * 24 * 360
                            && created.getTime() - 1000L * 60 * 60 * 24 * 360 <= ed) {
                        amount++;
                    }


                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTimeInMillis(ed - sd);
                    y2.setTitle(calendar2.get(Calendar.DAY_OF_MONTH) + "天");

                }

                y2.setAmount(amount);
                lastYear.add(y2);

                yearVo.setThisYear(thisYear);
                yearVo.setLastYear(lastYear);*/
                for (int i = 1; i <= day; i++) {
                    //今年
                    QueryWrapper<UserInfo> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.gt("created", new Date(sd + 1000L * 60 * 60 * 24 * (i - 1))).lt("created", new Date(sd + 1000L * 60 * 60 * 24 * i));

                    Integer count1 = this.userInfoService.queryCount(queryWrapper1);

                    Year y = new Year();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(sd + 1000L * 60 * 60 * 24 * i);
                    y.setTitle(calendar.get(Calendar.DAY_OF_MONTH) + "日");

                    y.setAmount(count1);
                    thisYear.add(y);

                    //去年
                    QueryWrapper<UserInfo> queryWrapper2 = new QueryWrapper<>();
                    queryWrapper2.ge("created", new Date(sd - 1000L * 60 * 60 * 24 * 365 + 1000L * 60 * 60 * 24 * (i - 1))).le("created", new Date(sd - 1000L * 60 * 60 * 24 * 365 + 1000L * 60 * 60 * 24 * i));

                    Integer count2 = this.userInfoService.queryCount(queryWrapper2);

                    Year y2 = new Year();
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTimeInMillis(sd + 1000L * 60 * 60 * 24 * i);
                    y2.setTitle(calendar2.get(Calendar.DAY_OF_MONTH) + "日");

                    y2.setAmount(count2);
                    lastYear.add(y2);
                }


                yearVo.setThisYear(thisYear);
                yearVo.setLastYear(lastYear);
                return yearVo;

            //活跃用户
            case (102):
                /*Date activeTime = null;

                for (Log log : logs) {
                    //日志表里用户操作的时间
                    activeTime = log.getActiveTime();
                    List<Integer> userId = new ArrayList<>();

                    //今年
                    if (activeTime.getTime() >= sd && activeTime.getTime() <= ed) {
                        //一个用户会操作多个接口,去重复
                        if (!userId.contains(log.getUserId())) {
                            userId.add(log.getUserId());
                            count++;
                        }
                    }

                    //去年
                    if (activeTime.getTime() >= sd - 1000L * 60 * 60 * 24 * 360 && activeTime.getTime() - 1000L * 60 * 60 * 24 * 360 <= ed) {
                        amount++;
                    }
                }

                return getVo(date, count, amount);*/

                for (int i = 1; i <= day; i++) {
                    //今年
                    QueryWrapper<Log> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.gt("active_time", new Date(sd + 1000L * 60 * 60 * 24 * (i - 1))).lt("active_time", new Date(sd + 1000L * 60 * 60 * 24 * i));

                    List<Log> logs1 = this.logService.queryLog(queryWrapper1);

                    //去重,一个用户一天多个操作
                    // Integer count1 = 0;
                    ArrayList<Integer> list = new ArrayList<>();
                    for (Log log : logs1) {
                        if (!list.contains(log.getUserId()))
                            list.add(log.getUserId());

                        // count1 = this.logService.queryCount(queryWrapper1);
                    }


                    Year y = new Year();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(sd + 1000L * 60 * 60 * 24 * i);
                    y.setTitle(calendar.get(Calendar.DAY_OF_MONTH) + "日");

                    y.setAmount(list.size());
                    thisYear.add(y);

                    //去年
                    QueryWrapper<Log> queryWrapper2 = new QueryWrapper<>();
                    queryWrapper2.ge("active_time", new Date(sd - 1000L * 60 * 60 * 24 * 365 + 1000L * 60 * 60 * 24 * (i - 1))).le("active_time", new Date(sd - 1000L * 60 * 60 * 24 * 365 + 1000L * 60 * 60 * 24 * i));

                    //当天是时间的日志
                    List<Log> logs2 = this.logService.queryLog(queryWrapper2);

                    //去重,一个用户一天多个操作
                    //Integer count2 = 0;
                    ArrayList<Integer> list1 = new ArrayList<>();
                    for (Log log : logs2) {
                        if (!list1.contains(log.getUserId()))
                            list1.add(log.getUserId());

                        //count2 = this.logService.queryCount(queryWrapper2);
                    }


                    Year y2 = new Year();
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTimeInMillis(sd + 1000L * 60 * 60 * 24 * i);
                    y2.setTitle(calendar2.get(Calendar.DAY_OF_MONTH) + "日");

                    y2.setAmount(list1.size());
                    lastYear.add(y2);
                }
                yearVo.setThisYear(thisYear);
                yearVo.setLastYear(lastYear);
                return yearVo;

            //次日留存率
            case (103):
               /* Date ctime = null;
                Date time = null;
                for (Log log : logs) {
                    time = log.getActiveTime();
                    for (UserInfo userInfo : userInfos) {
                        ctime = userInfo.getCreated();
                        //今年
                        //创建时间加上一天的时间在日志表的时间范围内
                        if (ctime.getTime() + 1000L * 60 * 60 * 24 <= time.getTime()
                                && time.getTime() <= ctime.getTime() + 1000L * 60 * 60 * 24 * 2
                                && time.getTime() >= sd && time.getTime() <= ed
                                && log.getUserId() == Integer.valueOf(userInfo.getUserId().toString())) {
                            count++;
                        }

                        //去年
                        if (ctime.getTime() + 1000L * 60 * 60 * 24 <= time.getTime()
                                && time.getTime() <= ctime.getTime() + 1000L * 60 * 60 * 24 * 2
                                && time.getTime() >= sd - 1000L * 60 * 60 * 24 * 360 && time.getTime() <= ed - 1000L * 60 * 60 * 24 * 360
                                && log.getUserId() == Integer.valueOf(userInfo.getUserId().toString())) {
                            amount++;
                        }

                        return getVo(date, count, amount);
                    }
                }*/

                for (int i = 1; i <= day; i++) {

                    //查出今年第i天的log
                    QueryWrapper<Log> queryWrapper3 = new QueryWrapper<>();
                    queryWrapper3.gt("active_time", new Date(sd + 1000L * 60 * 60 * 24 * (i - 1))).lt("active_time", new Date(sd + 1000L * 60 * 60 * 24 * i));
                    List<Log> logs1 = this.logService.queryLog(queryWrapper3);

                    Year y = new Year();
                    //今年
                    for (Log log : logs1) {

                        Date activeTime = log.getActiveTime();

                        QueryWrapper<UserInfo> queryWrapper1 = new QueryWrapper<>();
                        queryWrapper1.lt("created", activeTime).eq("user_id", log.getUserId())
                                .gt("created", new Date(activeTime.getTime() - 1000L * 60 * 60 * 24 - 1000L * 3));

                        Integer count1 = this.userInfoService.queryCount(queryWrapper1);

                        y.setAmount(count1);

                    }
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(sd + 1000L * 60 * 60 * 24 * i);
                    y.setTitle(calendar.get(Calendar.DAY_OF_MONTH) + "日");
                    thisYear.add(y);
                }


                for (int i = 1; i <= day; i++) {

                    //去年第i天的log
                    QueryWrapper<Log> queryWrapper4 = new QueryWrapper<>();
                    queryWrapper4.gt("active_time", new Date(sd - 1000L * 60 * 60 * 24 * 360 + 1000L * 60 * 60 * 24 * (i - 1)))
                            .lt("active_time", new Date(sd - 1000L * 60 * 60 * 24 * 365 + 1000L * 60 * 60 * 24 * i));
                    List<Log> logs2 = this.logService.queryLog(queryWrapper4);

                    Year y2 = new Year();
                    for (Log log : logs2) {
                        Date activeTime = log.getActiveTime();
                        //去年
                        QueryWrapper<UserInfo> queryWrapper2 = new QueryWrapper<>();
                        queryWrapper2.lt("created", activeTime).eq("user_id", log.getUserId())
                                .gt("created", new Date(activeTime.getTime() - 1000L * 60 * 60 * 24 - 1000L * 3));

                        Integer count2 = this.userInfoService.queryCount(queryWrapper2);

                        y2.setAmount(count2);

                    }

                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTimeInMillis(sd + 1000L * 60 * 60 * 24 * i);
                    y2.setTitle(calendar2.get(Calendar.DAY_OF_MONTH) + "日");
                    lastYear.add(y2);
                }
                yearVo.setThisYear(thisYear);
                yearVo.setLastYear(lastYear);
                return yearVo;

            default:
                return null;
        }
    }


   /* private YearVo getVo(Date date, Integer count, Integer amount) {

        YearVo yearVo = new YearVo();
        List<Year> thisYear = new ArrayList<>();
        List<Year> lastYear = new ArrayList<>();

        Year y = new Year();
        y.setTitle(date.getMonth() + "月");
        y.setAmount(count);
        thisYear.add(y);

        Year y2 = new Year();
        y2.setTitle(date.getMonth() + "月");
        y2.setAmount(amount);
        lastYear.add(y2);

        yearVo.setThisYear(thisYear);
        yearVo.setLastYear(lastYear);
        return yearVo;
    }*/

    /**
     * 注册用户分布，行业top、年龄、性别、地区
     *
     * @param sd
     * @param ed
     * @return
     */
    public DistributionVo queryDistribution(Long sd, Long ed) {

        //用户详情
        QueryWrapper<UserInfo> query = new QueryWrapper<>();
        List<UserInfo> userInfos = userInfoService.queryUserInfoList(query);

        //行业分布TOP10
        Set<Vo> vo1Set = new HashSet<>();
        Date created1 = null;
        List<String> list1 = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            created1 = userInfo.getCreated();
            //今年
            //if (created1.getTime() >= sd && created1.getTime() <= ed) {
            Vo vo1 = new Vo();

            //去重
            if (!list1.contains(userInfo.getIndustry())) {
                list1.add(userInfo.getIndustry());

                vo1.setTitle(userInfo.getIndustry());
                //查询数量
                QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("industry", vo1.getTitle());
                Integer count = userInfoService.queryCount(queryWrapper);

                vo1.setAmount(count);
                vo1Set.add(vo1);
            }

        }
        //}

        //年龄分布
        Set<Vo> vo2Set = new HashSet<>();

        List<Integer> list2 = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            Vo vo2 = new Vo();

            for (AgeRangeEnum value : AgeRangeEnum.values()) {
                if (userInfo.getAge() >= value.getMin() && userInfo.getAge() <= value.getMax()) {

                    //去重
                    if (!list2.contains(userInfo.getAge())) {
                        list2.add(userInfo.getAge());


                        vo2.setTitle(value.getMin() + "-" + value.getMax());

                        //查询数量
                        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                        queryWrapper.ge("age", value.getMin()).le("age", value.getMax());
                        Integer count = userInfoService.queryCount(queryWrapper);

                        vo2.setAmount(count);
                        vo2Set.add(vo2);
                    }
                }

            }
        }

        //性别分布
        Set<Vo> vo3Set = new HashSet<>();
        List<SexEnum> list3 = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            SexEnum sex = userInfo.getSex();

            Vo vo3 = new Vo();
            for (SexEnum value : SexEnum.values()) {

                //去重
                if (!list3.contains(userInfo.getSex())) {
                    list3.add(userInfo.getSex());

                    vo3.setTitle(userInfo.getSex().getValue() == 1 ? "男性用户" : "女性用户");

                    //查询数量
                    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("sex", sex.getValue());
                    Integer count = userInfoService.queryCount(queryWrapper);

                    vo3.setAmount(count);
                    vo3Set.add(vo3);
                }
            }
        }


        //地区分布
        Set<Vo> vo4Set = new HashSet<>();
        List<String> list4 = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            Vo vo4 = new Vo();

            String city = userInfo.getCity();
            String[] ss = city.split("-");
            String substring = ss[0].substring(0, 2);

            //去重
            if (!list4.contains(userInfo.getCity())) {
                list4.add(userInfo.getCity());

                vo4.setTitle(substring);

                //查询数量
                QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("city", city);
                Integer count = userInfoService.queryCount(queryWrapper);

                vo4.setAmount(count);
                vo4Set.add(vo4);
            }

        }


        //地区合计
        Set<Vo> vo5Set = new HashSet<>();
        List<String> list5 = new ArrayList<>();

        for (UserInfo userInfo : userInfos) {

            Vo vo5 = new Vo();
            String city = userInfo.getCity();
            String[] ss = city.split("-");
            String substring = ss[0].substring(0, 2);

            Integer i = 0;
            for (AreaEnum value : AreaEnum.values()) {

                String province = value.getProvince();

                if (substring.equals(province)) {
                    //去重
                    if (!list5.contains(userInfo.getCity())) {
                        list5.add(userInfo.getCity());

                        vo5.setTitle(value.getArea());

                        //查询数量
                        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("city", city);
                        Integer count = userInfoService.queryCount(queryWrapper);
                        i += count;

                        vo5.setAmount(i);
                        vo5Set.add(vo5);
                    }
                }
            }
        }

        DistributionVo distributionVo = new DistributionVo();
        distributionVo.setIndustryDistribution(vo1Set);
        distributionVo.setAgeDistribution(vo2Set);
        distributionVo.setGenderDistribution(vo3Set);
        distributionVo.setLocalDistribution(vo4Set);
        distributionVo.setLocalTotal(vo5Set);

        return distributionVo;
    }
}
